package com.example.demo.service.user.impl;

import com.example.demo.entity.exception.EnumException;
import com.example.demo.entity.security.Md5PasswordEncoder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Collection;

@RestController
@Service
public class MyAuthenticationProvider implements AuthenticationProvider {

    @Resource
    private UserServiceImpl userService;

    @PostConstruct
    public void setUserService() {
        if (userService == null) {
            userService = new UserServiceImpl ();
        }
    }


    @ApiOperation(value = "登录")
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 获取表单输入中返回的用户名;
        String userName = (String) authentication.getPrincipal ();
        // 获取表单中输入的密码；
        String password = (String) authentication.getCredentials ();
        // 这里调用我们的自己写的获取用户的方法；
        UserDetails userInfo = userService.loadUserByUsername ( userName );
        if (userInfo == null) {
//            throw new EnumException ( "用户名不存在" );
//            throw new RuntimeException( "用户名不存在" );
            throw new UsernameNotFoundException ( "用户名不存在" );
        }

        // 这里我们还要判断密码是否正确，这里我们的密码使用自定义进行加密的
        if (!new Md5PasswordEncoder ().matches ( password, userInfo.getPassword () )) {
            throw new UsernameNotFoundException ( "密码不正确" );
        }
        // 这里还可以加一些其他信息的判断，比如用户账号已停用等判断。

        Collection<? extends GrantedAuthority> authorities = userInfo.getAuthorities ();
        // 构建返回的用户登录成功的token
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken ( userInfo, password, authorities );
        return authenticationToken;
//        return new UserToken(  )
    }

    @Override
    public boolean supports(Class<?> authentication) {
//      这里直接改成retrun true;表示是支持这个执行
        return true;
    }
}
